#include "cue.hpp"

#include "stage.hpp"

#include "data.hpp"

bool CueGrid::Open(const std::string & name)
{
	Close();

	Data cuedat;
	if (!cuedat.Open(name))
		return false;

	for (Data cdat = cuedat.Begin(); cdat; ++cdat)
	{
		std::string cls;
		int dir = 1;
		Vec2i pos;

		for (Data d = cdat.Begin(); d; ++d)
		{
			if (d.Named("class"))
				cls = d.CStr();
			else if (d.Named("dir"))
				dir = d.Int();
			else if (d.Named("x"))
				pos.x = d.Int();
			else if (d.Named("y"))
				pos.y = d.Int();
		}

		Put(pos.x, pos.y, cls, dir);
	}
	
	cuedat.Close();

	return true;
}

static const char *STRINGS[Cue::CUECT] =
{
	// nil and static
	NULL, "door0", "door1", "door2", 
	"brk", "scrt xl", "scrt xxl", "scrt xxxl",
	"bossrm", NULL, NULL, NULL,
	NULL, NULL, NULL, NULL,

	// player
	"plr", "cp1", "cp2", "cp3", "pet", "petcp1", "petcp2", "petcp3",
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 

	// enemy
	"en ibox", "en drift", "en walk", "en fly",
	"en toss", "en rock", "en boss1", NULL,
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 

	// item
	"itm ammo s", "itm ammo l", "itm bns s", "itm bns m", 
	"itm bns l", "itm bns xl", "itm bns xxl", "itm bns xxxl",
	"itm bllt", "itm bubl", "itm cloud", "itm ball", "itm optn",
	"itm heal", "itm shld", "itm bomb",
	"itm clear", "itm melee", NULL, NULL, NULL, NULL, NULL, NULL,
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 

	// boat
	"boat"
};

bool CueGrid::Save(const std::string & name)
{
	Data cuedat;
	cuedat.InitArray();
	Data prev;
	for (int i = 0; i < cues.TileCt(); ++i)
	{
		Vec2i pos (cues.TileC(i), cues.TileR(i));
		Cue cue (Get(pos.x, pos.y));
		if (cue.Num() >= Cue::CUECT || !STRINGS[cue.Num()])
			continue;

		Data cdat;
		cdat.InitObj();

		Data cls (STRINGS[cue.Num()]);
		cdat.InsFront("class", cls);

		Data dir (cue.Dir());
		cdat.InsAfter(cls, "dir", dir);

		Data x (pos.x), y (pos.y);
		cdat.InsAfter(dir, "x", x);
		cdat.InsAfter(x, "y", y);

		prev = cuedat.InsAfter(prev, NULL, cdat);
	}

	return cuedat.Save(name);
}

#include <map>

std::map<std::string, int> strnums;

void CueGrid::Close()
{
	cues.Clear();
}

void CueGrid::Put(int c, int r, std::string & name, int face)
{
	if (strnums.empty())
	{
		for (int i = 1; i < Cue::CUECT; ++i)
		{
			if (STRINGS[i])
			{
				strnums[std::string(STRINGS[i])] = i;
			}
		}
	}

	std::map<std::string, int>::iterator strnum;
	strnum = strnums.find(name);
	if (strnum != strnums.end())
		Put(c, r, Cue(face * strnum->second));
}

#include "image.hpp"
#include "video.hpp"
    
void CueGrid::Draw(Image & cueimg)
{
	Vid.Pos(0, 0);
	Vid.Pri(1);
	Vid.Flip(false, false);
	Vid.TilesDraw(cueimg, cues.Data(), cues.Cols(), cues.Rows());
}

CueGrid Cues;
